/**
 * Copyright 2013-2015
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.terramagnet.learn.rabbitmq.consumer.framework;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;

/**
 *
 * @author lip
 */
public abstract class BatchedAsynchrony<T extends Serializable> extends Asynchrony<T> {

    private long millisWaitForBatch = 2000;
    private int batchSize = 2000;

    public void put(T... datas) {
        for (T d : datas) {
            super.put(d);
        }
    }

    @Override
    protected void take(T data) {
        ArrayList list = new ArrayList();
        list.add(data);
        take(list);
    }

    protected abstract void take(Collection<T> data);

    @Override
    protected Runnable runnable() {
        return new Runnable() {

            @Override
            public void run() {
                while (true) {
                    try {
                        T t = sharedQueue.take();
                        if (sharedQueue.isEmpty()) {
                            try {
                                logger.debug("wait for more data...");
                                Thread.sleep(getMillisWaitForBatch());
                            } catch (InterruptedException ex) {
                                take(t);
                                return;
                            }
                        }
                        ArrayList<T> datas = new ArrayList<T>();
                        datas.add(t);
                        sharedQueue.drainTo(datas, getBatchSize());
                        take(datas);
                    } catch (InterruptedException ex) {
                        logger.debug("停止线程：{}", getThreadName());
                        break;
                    } catch (Exception ex) {
                        logger.error(getThreadName() + "忽略了错误:" + ex.getMessage(), ex);
                    }
                }
            }
        };
    }

    protected long getMillisWaitForBatch() {
        return millisWaitForBatch;
    }

    protected int getBatchSize() {
        return batchSize;
    }

    public void setMillisWaitForBatch(long millisWaitForBatch) {
        this.millisWaitForBatch = millisWaitForBatch;
    }

    public void setBatchSize(int batchSize) {
        this.batchSize = batchSize;
    }
}
